<route lang="json5">
{
  style: {
    navigationStyle: 'custom'
  }
}
</route>

<script setup lang="ts">
import type {
  PunchDayVO,
  PunchStatsRespVO,
  PunchStatsVO,
} from '@/api/types/punch'
import type { ReadingHistoryRespVO } from '@/api/types/record'
import { onShow } from '@dcloudio/uni-app'
import { computed, onMounted, ref } from 'vue'
import {
  getPunchCalendar,
  getPunchStats,
} from '@/api/punch'
import { getReadingHistory } from '@/api/record'

interface DayData {
  date: string
  day: number
  isChecked: boolean
  isToday: boolean
  isCurrentMonth: boolean
}

interface MonthData {
  key: string
  title: string
  year: number
  month: number
  checkinDays: number
  totalDays: number
  days: DayData[]
}

// 加载状态
const loading = ref(false)
const loadingMore = ref(false)
const refreshing = ref(false)

// 日历数据
const calendarData = ref<MonthData[]>([])

// 分页相关
const hasMoreMonths = ref(true)
const currentLoadedMonths = ref(3) // 当前已加载的月份数
const maxMonthsToLoad = ref(12) // 最多加载12个月

// 打卡统计数据
const punchStats = ref<PunchStatsRespVO | null>(null)

// 当前月份的日历统计数据（从当前月份的日历API获取）
const currentMonthCalendarStats = ref<PunchStatsVO | null>(null)

// 当前月份统计 - 优先使用日历API的准确数据
const currentMonthCheckins = computed(() => {
  // 优先使用当前月份日历API返回的准确统计
  if (currentMonthCalendarStats.value) {
    return currentMonthCalendarStats.value.monthPunchDays || 0
  }
  // 备用：使用全局统计API的数据
  return punchStats.value?.thisMonthPunchDays || 0
})

const currentMonthStreak = computed(() => {
  // 优先使用当前月份日历API返回的准确统计
  if (currentMonthCalendarStats.value) {
    return currentMonthCalendarStats.value.currentStreak || 0
  }
  // 备用：使用全局统计API的数据
  return punchStats.value?.consecutiveDays || 0
})

// 累计打卡天数
const totalPunchDays = computed(() => {
  // 优先使用当前月份日历API返回的准确统计
  if (currentMonthCalendarStats.value) {
    return currentMonthCalendarStats.value.totalPunchDays || 0
  }
  // 备用：使用全局统计API的数据
  return punchStats.value?.totalPunchDays || 0
})

// 本月打卡率
const punchRate = computed(() => {
  const now = new Date()
  const currentDay = now.getDate()
  const checkins = currentMonthCheckins.value

  if (currentDay === 0)
    return null

  return Math.round((checkins / currentDay) * 100)
})

// 打卡率显示格式
const punchRateDisplay = computed(() => {
  return punchRate.value || 0
})

// 日期详情弹窗相关
const showDateDetailModal = ref(false)
const selectedDate = ref('')
const selectedDateBooks = ref<ReadingHistoryRespVO[]>([])
const loadingDateBooks = ref(false)

// 加载打卡统计数据
async function loadPunchStats() {
  try {
    const response = await getPunchStats()
    if (response.code === 0) {
      punchStats.value = response.data
    }
  }
  catch (error) {
    console.error('获取打卡统计失败:', error)
  }
}

// 加载打卡日历数据
async function loadPunchCalendar(year: number, month: number) {
  try {
    // 后端期望的参数格式是 yearMonth: "2024-01"
    const yearMonth = `${year}-${month.toString().padStart(2, '0')}`
    const response = await getPunchCalendar({ yearMonth })
    console.log('打卡日历API响应:', response) // 调试日志

    if (response && response.code === 0) {
      const calendarData = response.data
      console.log('打卡日历数据:', calendarData) // 调试日志

      // 检查是否是当前月份，如果是则保存统计数据
      const now = new Date()
      const currentYear = now.getFullYear()
      const currentMonth = now.getMonth() + 1

      if (year === currentYear && month === currentMonth && calendarData?.stats) {
        currentMonthCalendarStats.value = calendarData.stats
        console.log('保存当前月份统计数据:', calendarData.stats)
      }

      // 后端返回的是 PunchCalendarRespVO 对象，包含 punchDays 数组
      if (calendarData && calendarData.punchDays && Array.isArray(calendarData.punchDays)) {
        console.log('返回打卡天数数据:', calendarData.punchDays.length, '条记录')
        return calendarData.punchDays
      }
      else {
        console.warn('打卡日历数据格式不正确:', calendarData)
        return []
      }
    }
    else {
      console.warn('API响应格式不正确:', response)
    }
  }
  catch (error) {
    console.error('获取打卡日历失败:', error)
  }
  return []
}

// 生成日历数据
async function generateCalendarData(monthsToLoad: number = 3, append: boolean = false) {
  const now = new Date()
  const currentYear = now.getFullYear()
  const currentMonth = now.getMonth() + 1

  const months: MonthData[] = []

  // 计算起始月份偏移量
  const startOffset = append ? currentLoadedMonths.value : 0

  // 生成指定数量的月份数据
  for (let i = startOffset; i < startOffset + monthsToLoad; i++) {
    const targetMonth = currentMonth - i
    let targetYear = currentYear
    let actualMonth = targetMonth

    // 处理跨年情况
    while (actualMonth <= 0) {
      actualMonth += 12
      targetYear -= 1
    }

    // 获取该月的打卡数据
    const punchCalendarData = await loadPunchCalendar(targetYear, actualMonth)
    const monthData = generateMonthData(targetYear, actualMonth, punchCalendarData)
    months.push(monthData)
  }

  if (append) {
    calendarData.value.push(...months)
    currentLoadedMonths.value += monthsToLoad
  }
  else {
    calendarData.value = months
    currentLoadedMonths.value = monthsToLoad
  }

  // 检查是否还有更多月份可以加载
  hasMoreMonths.value = currentLoadedMonths.value < maxMonthsToLoad.value
}

// 生成单月数据
function generateMonthData(year: number, month: number, punchCalendarData: PunchDayVO[] = []): MonthData {
  // 确保 punchCalendarData 是数组
  const safeCalendarData = Array.isArray(punchCalendarData) ? punchCalendarData : []
  console.log(`生成${year}年${month}月数据，打卡记录数:`, safeCalendarData.length)
  const daysInMonth = new Date(year, month, 0).getDate()
  const firstDayOfWeek = new Date(year, month - 1, 1).getDay()
  const today = new Date()

  const days: DayData[] = []

  // 添加空白天数（上个月的日期）
  for (let i = 0; i < firstDayOfWeek; i++) {
    const prevMonth = month === 1 ? 12 : month - 1
    const prevYear = month === 1 ? year - 1 : year
    const prevMonthDays = new Date(prevYear, prevMonth, 0).getDate()
    const day = prevMonthDays - firstDayOfWeek + i + 1

    days.push({
      date: `${prevYear}-${prevMonth.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`,
      day,
      isChecked: false,
      isToday: false,
      isCurrentMonth: false,
    })
  }

  // 添加当月日期
  let checkinDays = 0

  for (let day = 1; day <= daysInMonth; day++) {
    const isToday = year === today.getFullYear()
      && month === today.getMonth() + 1
      && day === today.getDate()

    const dateStr = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`

    // 从API数据中查找该日期是否有打卡记录
    // 处理日期格式匹配问题：后端返回数组格式 [2025, 7, 19]
    const punchRecord = safeCalendarData.find((record) => {
      if (!record.date)
        return false

      let recordDateStr = ''
      if (Array.isArray(record.date)) {
        // 后端返回数组格式 [年, 月, 日]
        const [year, month, day] = record.date
        recordDateStr = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`
      }
      else if (typeof record.date === 'string') {
        // 字符串格式
        recordDateStr = record.date
      }
      else {
        // 其他格式转换为字符串
        recordDateStr = String(record.date)
      }

      return recordDateStr === dateStr
    })
    const isChecked = !!punchRecord?.isPunched

    // console.log(`日期匹配检查: ${dateStr}, 后端数据:`, safeCalendarData.find(r => r.date)?.date, '找到记录:', punchRecord) // 调试日志

    if (isChecked)
      checkinDays++

    days.push({
      date: dateStr,
      day,
      isChecked,
      isToday,
      isCurrentMonth: true,
    })
  }

  // 补充下个月的日期到42个（6周）
  const remainingDays = 42 - days.length
  const nextMonth = month === 12 ? 1 : month + 1
  const nextYear = month === 12 ? year + 1 : year

  for (let day = 1; day <= remainingDays; day++) {
    days.push({
      date: `${nextYear}-${nextMonth.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`,
      day,
      isChecked: false,
      isToday: false,
      isCurrentMonth: false,
    })
  }

  return {
    key: `${year}-${month}`,
    title: `${month.toString().padStart(2, '0')}月`,
    year,
    month,
    checkinDays,
    totalDays: daysInMonth,
    days,
  }
}

// 获取日期样式类
function getDayClass(day: DayData) {
  const classes = []

  if (!day.isCurrentMonth) {
    classes.push('other-month')
  }

  if (day.isChecked && day.isCurrentMonth) {
    classes.push('checked')
  }

  if (day.isToday) {
    classes.push('today')
  }

  return classes.join(' ')
}

// 加载更多月份
async function loadMoreMonths() {
  if (loadingMore.value || !hasMoreMonths.value)
    return

  try {
    loadingMore.value = true
    await generateCalendarData(3, true) // 每次加载3个月
  }
  catch (error) {
    console.error('加载更多月份失败:', error)
    uni.showToast({
      title: '加载失败',
      icon: 'none',
    })
  }
  finally {
    loadingMore.value = false
  }
}

// 下拉刷新
async function onRefresh() {
  try {
    refreshing.value = true
    currentLoadedMonths.value = 0
    hasMoreMonths.value = true

    await Promise.all([
      loadPunchStats(),
      generateCalendarData(3, false), // 重新加载最近3个月
    ])
  }
  catch (error) {
    console.error('刷新失败:', error)
    uni.showToast({
      title: '刷新失败',
      icon: 'none',
    })
  }
  finally {
    refreshing.value = false
  }
}

// 返回上一页
function goBack() {
  uni.navigateBack({
    fail() {
      uni.reLaunch({
        url: '/pages/study-checkin/index',
      })
    },
  })
}

// 格式化日期显示
function formatDateDisplay(dateStr: string) {
  const date = new Date(dateStr)
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  return `${year}年${month.toString().padStart(2, '0')}月${day.toString().padStart(2, '0')}日`
}

// 点击已打卡日期
async function onDateClick(day: DayData) {
  // 只有已打卡且是当月的日期才能点击
  if (!day.isChecked || !day.isCurrentMonth) {
    return
  }

  try {
    selectedDate.value = day.date
    showDateDetailModal.value = true
    loadingDateBooks.value = true
    selectedDateBooks.value = []

    // 获取该日期的阅读记录
    await loadDateReadingRecords(day.date)
  }
  catch (error) {
    console.error('获取日期阅读记录失败:', error)
    uni.showToast({
      title: '获取数据失败',
      icon: 'none',
    })
  }
  finally {
    loadingDateBooks.value = false
  }
}

// 获取指定日期的阅读记录
async function loadDateReadingRecords(dateStr: string) {
  try {
    // 使用阅读历史接口获取数据，然后在前端过滤指定日期
    const response = await getReadingHistory({
      page: 1,
      size: 100, // 获取足够多的数据进行过滤
    })

    if (response.code === 0 && response.data) {
      // 过滤出指定日期的阅读记录
      const targetDate = new Date(dateStr)
      const filteredBooks = response.data.filter((record) => {
        const recordDate = new Date(record.lastReadAt)
        return (
          recordDate.getFullYear() === targetDate.getFullYear()
          && recordDate.getMonth() === targetDate.getMonth()
          && recordDate.getDate() === targetDate.getDate()
        )
      })

      selectedDateBooks.value = filteredBooks
    }
  }
  catch (error) {
    console.error('获取阅读记录失败:', error)
    throw error
  }
}

// 隐藏日期详情弹窗
function hideDateDetailModal() {
  showDateDetailModal.value = false
  selectedDate.value = ''
  selectedDateBooks.value = []
}

// 图片加载失败处理
function onImageError(event: any) {
  console.log('图片加载失败:', event)
  // 可以设置默认图片
}

// 页面显示时刷新数据（从打卡页面返回时）
onShow(async () => {
  // 只在非首次加载时刷新数据
  if (!loading.value && calendarData.value.length > 0) {
    try {
      console.log('页面显示时刷新打卡日历数据')
      await Promise.all([
        loadPunchStats(),
        generateCalendarData(3, false), // 重新加载最近3个月
      ])
    }
    catch (error) {
      console.error('页面显示时数据刷新失败:', error)
    }
  }
})

onMounted(async () => {
  loading.value = true
  try {
    await Promise.all([
      loadPunchStats(),
      generateCalendarData(3, false), // 初始加载最近3个月
    ])
  }
  catch (error) {
    console.error('初始化数据失败:', error)
    uni.showToast({
      title: '数据加载失败',
      icon: 'none',
    })
  }
  finally {
    loading.value = false
  }
})
</script>

<template>
  <view class="calendar-container">
    <!-- 自定义导航栏 -->
    <view class="custom-navbar">
      <view class="navbar-content">
        <view class="navbar-left" @click="goBack">
          <uni-icons type="left" size="20" color="#333" />
        </view>
        <view class="navbar-title">
          <text class="title-text">
            打卡日历
          </text>
        </view>
        <view class="navbar-right" />
      </view>
    </view>

    <!-- 本月打卡统计 -->
    <view class="month-stats">
      <text class="stats-title">
        本月打卡统计
      </text>
      <view class="stats-row">
        <view class="stat-item">
          <text class="stat-number">
            {{ currentMonthCheckins }}
          </text>
          <text class="stat-label">
            打卡天数
          </text>
        </view>
        <view class="stat-item">
          <text class="stat-number">
            {{ currentMonthStreak }}
          </text>
          <text class="stat-label">
            连续天数
          </text>
        </view>
        <view class="stat-item">
          <text class="stat-number">
            {{ totalPunchDays }}
          </text>
          <text class="stat-label">
            累计天数
          </text>
        </view>
      </view>
    </view>

    <!-- 日历列表 -->
    <scroll-view
      class="calendar-scroll"
      scroll-y
      :refresher-enabled="true"
      :refresher-triggered="refreshing"
      @scrolltolower="loadMoreMonths"
      @refresherrefresh="onRefresh"
    >
      <view class="calendar-list">
        <view v-for="month in calendarData" :key="month.key" class="month-section">
          <view class="month-header">
            <text class="month-title">
              {{ month.title }}
            </text>
            <text class="month-stats-text">
              打卡天数: {{ month.checkinDays }}/{{ month.totalDays }}
            </text>
          </view>

          <!-- 周标题 -->
          <view class="week-header">
            <text class="week-day">
              日
            </text>
            <text class="week-day">
              一
            </text>
            <text class="week-day">
              二
            </text>
            <text class="week-day">
              三
            </text>
            <text class="week-day">
              四
            </text>
            <text class="week-day">
              五
            </text>
            <text class="week-day">
              六
            </text>
          </view>

          <view class="calendar-grid">
            <view
              v-for="day in month.days"
              :key="day.date"
              class="day-item"
              :class="getDayClass(day)"
              @click="onDateClick(day)"
            >
              <text class="day-text">
                {{ day.day }}
              </text>
            </view>
          </view>
        </view>

        <!-- 加载更多提示 -->
        <view v-if="hasMoreMonths" class="load-more">
          <text v-if="loadingMore" class="load-text">
            加载中...
          </text>
          <text v-else class="load-text">
            下拉加载更多月份
          </text>
        </view>

        <!-- 没有更多数据提示 -->
        <view v-else-if="calendarData.length > 0" class="no-more">
          <text class="no-more-text">
            没有更多数据了
          </text>
        </view>
      </view>
    </scroll-view>

    <!-- 日期详情弹窗 -->
    <view v-if="showDateDetailModal" class="detail-modal-overlay" @click="hideDateDetailModal">
      <view class="detail-modal-content" @click.stop>
        <!-- 关闭按钮 -->
        <view class="modal-close-btn" @click="hideDateDetailModal">
          <wd-icon name="close-normal" size="22px" color="#666"></wd-icon>
        </view>

        <!-- 滚动容器 -->
        <scroll-view class="modal-scroll-container" :scroll-y="true" :enhanced="true" :show-scrollbar="false">
          <!-- 标题 -->
          <view class="modal-books-header">
            <view class="books-header">
              <!-- <text class="books-icon">📚</text> -->
              <text class="books-title">{{ formatDateDisplay(selectedDate) }}</text>
            </view>
            <text class="books-count">共{{ selectedDateBooks.length }}本</text>
          </view>

          <!-- 分割线 -->
          <view class="modal-divider" />

          <!-- 加载状态 -->
          <view v-if="loadingDateBooks" class="modal-loading">
            <text class="loading-text">加载中...</text>
          </view>

          <!-- 绘本网格 -->
          <view v-else-if="selectedDateBooks.length > 0" class="modal-books-section">
            <view class="modal-books-grid">
              <view v-for="book in selectedDateBooks" :key="book.id" class="modal-book-item">
                <image
                  class="modal-book-cover"
                  :src="book.bookCover"
                  mode="aspectFill"
                  @error="onImageError"
                />
                <text class="modal-book-title">{{ book.bookTitle }}</text>
                <view class="book-progress">
                  <text class="progress-text">
                    {{ book.isCompleted ? '已完成' : `进度 ${Math.round(book.readingProgress * 100)}%` }}
                  </text>
                </view>
              </view>
            </view>
          </view>

          <!-- 无数据提示 -->
          <view v-else class="modal-empty">
            <text class="empty-text">该日期暂无阅读记录</text>
          </view>
        </scroll-view>
      </view>
    </view>
  </view>
</template>

<style lang="scss" scoped>
// 导入公共样式变量
@import '@/styles/variables.scss';

.calendar-container {
  background: $bg-gradient;
  min-height: 100%;
  padding-top: 40px;
}

/* 自定义导航栏 - 儿童友好风格 */
.custom-navbar {
  @include glass-effect;
  padding-top: var(--status-bar-height, 20px);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: $z-index-sticky;
  box-shadow: $shadow-lg;
  border-bottom: 1px solid $border-color-light;

  .navbar-content {
    display: flex;
    align-items: center;
    height: $height-lg;
    padding: 0 $spacing-xl;

    .navbar-left {
      width: $height-lg;
      height: $height-lg;
      @include center-flex;
      border-radius: $border-radius-lg;
      transition: $transition-colors;
      @include click-scale;

      &:hover {
        background-color: rgba(66, 187, 255, 0.1);
      }

      &:active {
        background-color: rgba(66, 187, 255, 0.2);
      }
    }

    .navbar-title {
      flex: 1;
      @include center-flex;

      .title-text {
        font-size: $font-size-xl;
        font-weight: $font-weight-bold;
        color: $dark-gray;
        font-family: $font-family;
        letter-spacing: 0.5px;
      }
    }

    .navbar-right {
      width: $height-lg;
    }
  }
}

/* 本月统计 - 儿童友好风格 */
.month-stats {
  background: $blue-gradient;
  margin: 44px $container-padding $section-margin $container-padding;
  border-radius: $border-radius-xl;
  padding: $card-padding-lg $card-padding;
  box-shadow: $shadow-blue-lg;
  @include hover-lift;

  .stats-title {
    font-size: $font-size-lg;
    font-weight: $font-weight-semibold;
    color: $white;
    margin-bottom: $spacing-2xl;
    text-align: center;
    font-family: $font-family;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }

  .stats-row {
    display: flex;
    justify-content: space-around;
    gap: $spacing-lg;

    .stat-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      flex: 1;
      padding: $spacing-md;
      border-radius: $border-radius-lg;
      background: $white-20;
      transition: $transition-all;

      &:hover {
        background: $white-30;
        transform: translateY(-2px);
      }

      .stat-number {
        font-size: $font-size-3xl;
        font-weight: $font-weight-extrabold;
        color: $white;
        margin-bottom: $spacing-sm;
        font-family: $font-family;
        text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
      }

      .stat-label {
        font-size: $font-size-base;
        color: $white-90;
        font-weight: $font-weight-medium;
        font-family: $font-family;
      }
    }
  }
}

/* 日历滚动容器 */
.calendar-scroll {
  height: calc(100vh - 300rpx); /* 减去导航栏和统计区域的高度 */
}

/* 日历列表 - 儿童友好风格 */
.calendar-list {
  padding: 0 $container-padding $spacing-3xl $container-padding;

  .month-section {
    @include card-container;

    & {
      animation: slideInUp 0.6s ease-out;
    }

    .month-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: $spacing-xl;
      padding-bottom: $spacing-md;
      border-bottom: 1px solid $border-color-light;

      .month-title {
        font-size: $font-size-xl;
        font-weight: $font-weight-bold;
        color: $dark-gray;
        font-family: $font-family;
        letter-spacing: 0.5px;
      }

      .month-stats-text {
        font-size: $font-size-base;
        color: $primary-blue;
        font-weight: $font-weight-medium;
        background: rgba(66, 187, 255, 0.1);
        padding: $spacing-xs $spacing-md;
        border-radius: $border-radius-lg;
        font-family: $font-family;
        transition: $transition-all;

        &:hover {
          background: rgba(66, 187, 255, 0.2);
        }
      }
    }

    .week-header {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: $spacing-sm;
      margin-bottom: $spacing-md;

      .week-day {
        text-align: center;
        font-size: $font-size-base;
        font-weight: $font-weight-semibold;
        color: $medium-gray;
        padding: $spacing-sm 0;
        font-family: $font-family;
      }
    }

    .calendar-grid {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: $spacing-sm;

      .day-item {
        aspect-ratio: 1;
        @include center-flex;
        border-radius: $border-radius-lg;
        transition: $transition-all;
        position: relative;
        cursor: pointer;

        .day-text {
          font-size: $font-size-base;
          font-weight: $font-weight-semibold;
          transition: $transition-all;
          font-family: $font-family;
        }

        &.other-month {
          .day-text {
            color: $border-gray;
            font-weight: $font-weight-regular;
          }
        }

        &.checked {
          background: $green-gradient;
          box-shadow: $shadow-green;
          transform: scale(1.05);

          .day-text {
            color: $white;
            font-weight: $font-weight-bold;
            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
          }

          &:hover {
            box-shadow: 0 6px 16px rgba(50, 205, 50, 0.4);
          }
        }

        &.today {
          border: 2px solid $primary-blue;

          &:not(.checked) {
            background: rgba(66, 187, 255, 0.1);

            .day-text {
              color: $primary-blue;
              font-weight: $font-weight-bold;
            }
          }

          &.checked {
            // 今天已打卡：保持绿色背景，添加蓝色边框强调
            background: $green-gradient;
            border: 3px solid $primary-blue;
            box-shadow:
              $shadow-green,
              0 0 0 1px $white,
              0 0 8px rgba(66, 187, 255, 0.5);
            transform: scale(1.08); // 稍微放大突出显示

            .day-text {
              color: $white;
              font-weight: $font-weight-bold;
              text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
            }

            &:hover {
              box-shadow:
                $shadow-green,
                0 0 0 1px $white,
                0 0 12px rgba(66, 187, 255, 0.7);
            }
          }
        }

        &:not(.other-month):not(.checked):not(.today) {
          background-color: $light-gray;

          .day-text {
            color: $medium-gray;
          }

          &:hover {
            background: rgba(66, 187, 255, 0.1);
            transform: scale(1.05);

            .day-text {
              color: $primary-blue;
            }
          }
        }

        // 已打卡日期添加点击效果
        &.checked {
          cursor: pointer;

          &:active {
            transform: scale(1.02);
          }
        }
      }
    }
  }

  /* 加载更多提示 */
  .load-more {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: $spacing-xl 0;
    margin-top: $spacing-lg;

    .load-text {
      color: $medium-gray;
      font-size: $font-size-sm;
      font-family: $font-family;
    }
  }

  /* 没有更多数据提示 */
  .no-more {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: $spacing-xl 0;
    margin-top: $spacing-lg;

    .no-more-text {
      color: $medium-gray;
      font-size: $font-size-sm;
      font-family: $font-family;
    }
  }
}

/* 动画效果 */
@keyframes slideInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(50px) scale(0.9);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* 弹窗样式 */
.detail-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: $spacing-lg;
  animation: fadeIn 0.3s ease-out;
}

.detail-modal-content {
  background: $white;
  border-radius: $border-radius-xl;
  width: 90%;
  max-width: 500px;
  max-height: 80vh;
  position: relative;
  box-shadow: $shadow-lg;
  overflow: hidden;
  animation: slideUp 0.3s ease-out;
}

.modal-close-btn {
  position: absolute;
  top: $spacing-md;
  right: $spacing-md;
  width: 32px;
  height: 32px;
  @include center-flex;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.1);
  z-index: 10;
  transition: $transition-all;

  &:hover {
    background: rgba(0, 0, 0, 0.2);
  }
}

.modal-scroll-container {
  height: 100%;
  max-height: 70vh;
}

.modal-divider {
  height: 1px;
  background: $border-color-light;
  margin: 0 $spacing-lg;
}

.modal-books-header {
  padding: $spacing-lg 0;
  text-align: center;

  .books-header {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: $spacing-sm;
    margin-bottom: $spacing-sm;

    .books-icon {
      font-size: $font-size-xl;
    }

    .books-title {
      font-size: $font-size-lg;
      font-weight: $font-weight-bold;
      color: $dark-gray;
      font-family: $font-family;
    }
  }

  .books-count {
    font-size: $font-size-base;
    color: $primary-blue;
    font-weight: $font-weight-medium;
    background: rgba(66, 187, 255, 0.1);
    padding: $spacing-xs $spacing-md;
    border-radius: $border-radius-lg;
    display: inline-block;
    font-family: $font-family;
  }
}

.modal-books-section {
  padding: $spacing-lg;
}

.modal-books-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: $spacing-md;
}

.modal-book-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;

  .modal-book-cover {
    width: 70px;
    height: 90px;
    border-radius: $border-radius-md;
    margin-bottom: $spacing-sm;
    box-shadow: $shadow-md;
  }

  .modal-book-title {
    font-size: $font-size-sm;
    color: $dark-gray;
    font-family: $font-family;
    font-weight: $font-weight-medium;
    line-height: $line-height-tight;
    margin-bottom: $spacing-xs;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .book-progress {
    .progress-text {
      font-size: $font-size-xs;
      color: $medium-gray;
      font-family: $font-family;
    }
  }
}

.modal-loading {
  padding: $spacing-3xl;
  text-align: center;

  .loading-text {
    font-size: $font-size-base;
    color: $medium-gray;
    font-family: $font-family;
  }
}

.modal-empty {
  padding: $spacing-3xl;
  text-align: center;

  .empty-text {
    font-size: $font-size-base;
    color: $medium-gray;
    font-family: $font-family;
  }
}
</style>
